package cloud.xlh.digital_power_order.disruptor;

/**
 * Created with IntelliJ IDEA.
 *
 * @ project name : xlh_osms
 * @ Author: XuLeHuang
 * @ Date: 2023/8/22 22:11
 * @ Description: 订单消费者
 */

import cloud.xlh.digital_power_order.config.rabbitmq.RabbitMQConstant;
import cloud.xlh.digital_power_order.config.rabbitmq.RabbitMQOperateService;
import cloud.xlh.digital_power_order.enums.OrderStatusEnum;
import cloud.xlh.digital_power_order.infrastructure.order.entity.OrderEntity;
import cloud.xlh.digital_power_order.infrastructure.order.mapper.OrderEntityMapper;
import cloud.xlh.digital_power_order.util.StringUtil;
import cloud.xlh.infrastructure.utils.DateUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.WorkHandler;
import com.mybatisflex.core.update.UpdateChain;
import jdk.nashorn.internal.runtime.logging.Logger;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.HashMap;

@Logger
@Slf4j
//EventHandler用于EventHandlerGroup，WorkHandler用于WorkPool。同时实现两接口，该类对象可同时用于EventHandlerGroup和WorkPool
public class OrderHandler implements EventHandler<OrderEntity>, WorkHandler<OrderEntity> {
    private String consumerId;

    public OrderHandler(String consumerId) {
        this.consumerId = consumerId;
    }

    public String getConsumerId() {
        return consumerId;
    }

    //EventHandler的方法
    @Override
    public void onEvent(OrderEntity orderEntity, long sequence, boolean endOfBatch) throws Exception {
        System.out.println("OrderHandler " + this.consumerId + "，消费信息：" + orderEntity.getOrderNo());
    }

    //WorkHandler的方法
    @Override
    public void onEvent(OrderEntity orderEntity) {
        try {
            OrderEntityMapper orderEntityMapper = (OrderEntityMapper) SpringUtil.getBean(StringUtil.setFirstByteLowerCase(OrderEntityMapper.class.getSimpleName()));

            //入库
            orderEntityMapper.insert(orderEntity);
            System.out.println("OrderHandler " + this.consumerId + "，消费信息：" + orderEntity.getOrderNo());
        } catch (Exception e) {
            log.error("error message->{}，cause->{}" , e.getMessage() , e.getCause());
            e.printStackTrace();
            UpdateChain.of(OrderEntity.class)
                    .set(OrderEntity::getStatus, OrderStatusEnum.LOCAL_FAIL.getCode())
                    .set(OrderEntity::getUpdateTime , DateUtil.toAppointPatternLocalDateTimeStr(LocalDateTime.now() , DateUtil.HHMMSS_FORMAT))
                    .where(OrderEntity::getOrderNo).eq(orderEntity.getOrderNo())
                    .update();
            throw new RuntimeException(e.getMessage() , e.getCause());
        }
        try {
            //远程调用聚合支付系统
           /* OrderServiceAdapter orderServiceAdapter = (OrderServiceAdapter) SpringUtil.getBean(StringUtil.setFirstByteLowerCase(OrderServiceAdapter.class.getSimpleName()));
            OrderSaveDomain orderSaveDomain = orderServiceAdapter.convertOrderSaveDomain(null , orderEntity);
            RemoteCallManageService remoteCallManageService = (RemoteCallManageService) SpringUtil.getBean(StringUtil.setFirstByteLowerCase(RemoteCallManageService.class.getSimpleName()));
            DigitalPowerPayRemoteCall digitalPowerPayRemoteCall = (DigitalPowerPayRemoteCall) remoteCallManageService.getRemoteCallService(StringUtil.setFirstByteLowerCase(DigitalPowerPayRemoteCall.class.getSimpleName()));
            String result = digitalPowerPayRemoteCall.genOrder(orderSaveDomain);
            UpdateChain.of(OrderEntity.class)
                    .set(OrderEntity::getStatus, OrderStatusEnum.REMOTE_SUCCESS.getCode())
                    .where(OrderEntity::getOrderNo).eq(orderEntity.getOrderNo())
                    .update();*/
            //todo 难点：如何将远程调用的结果反馈给主线程，涉及到线程间的通信
            //todo 通知手机app端或者h5端拉起支付页面
            //todo 15分钟未支付订单自动取消 死信队列
            RabbitMQOperateService rabbitMQOperateService =  SpringUtil.getBean(StringUtil.setFirstByteLowerCase(RabbitMQOperateService.class.getSimpleName()));
            HashMap<String, String> parmaMap = new HashMap<>();
            parmaMap.put("exchange" , RabbitMQConstant.COMMON_ORDER_EXCHANGE_NAME);
            parmaMap.put("routingKey" , RabbitMQConstant.ORDER_DELAY_EXPIRE_ROUTING_KEY);
            parmaMap.put("message" , orderEntity.getOrderNo());
            //15分钟过期
            parmaMap.put("ttl" , "900000");
            log.info("生产者向mq服务端发送消息，exchange：[{}]，routingKey:[{}]，message：[{}]，ttl：[{}]"
                    , parmaMap.get("exchange") , parmaMap.get("routingKey") , parmaMap.get("message") , parmaMap.get("ttl"));
            rabbitMQOperateService.process(parmaMap);

        } catch (Exception e) {
            log.error("error message->{}，cause->{}" , e.getMessage() , e.getCause());
            e.printStackTrace();
            UpdateChain.of(OrderEntity.class)
                    .set(OrderEntity::getStatus, OrderStatusEnum.REMOTE_EXCEPTION.getCode())
                    .set(OrderEntity::getUpdateTime , DateUtil.toAppointPatternLocalDateTimeStr(LocalDateTime.now() , DateUtil.HHMMSS_FORMAT))
                    .where(OrderEntity::getOrderNo).eq(orderEntity.getOrderNo())
                    .update();
            throw new RuntimeException(e.getMessage() , e.getCause());
        }
    }
}
